package com.turing.post.tuxedo.util;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;

import com.turing.post.transaction.util.MrchTransParam;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;

/**
 * 商户交易本地服务接口实现
 * 
 * @author yxb
 * 
 */
public class LocalServiceImpl implements LocalService {
	@Resource
	protected EJBContext ejbContext;

	/**
	 * 返回当前EJB上下文
	 * 
	 * @return
	 */
	public EJBContext getEjbContext() {
		return ejbContext;
	}

	@EJB(mappedName = "tuxedo.service.PCPSServiceHelperImpl")
	protected PCPSServiceHelper serviceHelper;

	/**
	 * 获取PCPS服务的上下文
	 * 
	 * @return
	 */
	public PCPSServiceHelper getServiceHelper() {
		return serviceHelper;
	}

	/**
	 * 产生请求对象
	 * 
	 * @return
	 */
	protected TransRequest makeRequestObject() {
		return null;
	}

	/**
	 * 交易前检查阶段
	 * 
	 * @param req
	 * @param ack
	 * @throws PCPSApplicationException
	 */
	protected void preService(TransRequest req, TransResponse ack)
			throws PCPSApplicationException {
	}

	/**
	 * 业务逻辑阶段,如记载相关的数据库表
	 * 
	 * @param req
	 * @param ack
	 * @throws PMBSApplicationException
	 */
	protected void Service(TransRequest req, TransResponse ack)
			throws PCPSApplicationException {
	}

	protected MrchTransParam setMrchTransParam(TransRequest req)
			throws PCPSApplicationException {
		// 设置调用参数
		MrchTransParam imtp = new MrchTransParam();

		// 当前时间
		imtp.curSysDateTime = req.curSysDateTime;
		// 发卡商
		imtp.issueCompanyNo = req.issueCompany.getIssueCompanyNo();
		// 商户号
		imtp.merchantNo = req.merchantNo;
		// 商户帐务日期
		imtp.tranDate = req.tranDate;

		// 商户交易流水号
		imtp.mrchReqSeqNo = req.reqSeqNo;
		// 商户机构号(必选)
		imtp.mrchBrchNo = req.brchNo;
		// 商户柜员号(可选)
		imtp.mrchTellerNo = req.tellerNo;
		// 商户机构名称(可选)
		imtp.mrchBrchName = req.brchName;
		// 商户柜员姓名(可选)
		imtp.mrchTellerName = req.tellerName;
		// // 交易摘要(可选)
		// imtp.mrchAbstract = itr.asbtract;

		if (req.posObj != null) {
			// POS号(POS商户必选)
			imtp.mrchPosNo = req.posObj.posNo;
			// POS批次号(POS商户必选)
			imtp.mrchPosBatchNo = req.posObj.posSettBatchNo;
			// POS流水号(POS商户必选)
			imtp.mrchPosSeqNo = req.posObj.posSeqNo;
		}

		return imtp;
	}

	/**
	 * 一般性交易服务实现框架
	 * 
	 * @param req
	 * @return AckHdr
	 * @throws PMBSApplicationException
	 */
	protected final TransResponse CommonService(TransRequest req,
			TransResponse ack) throws PCPSApplicationException {

		PCPSServiceHelper sc = getServiceHelper();

		// step 0: 一般性检查
		req = sc.validateRequest(req);

		// 设置返回报文中的交易码
		ack.tranCode = req.tranCode;

		// 设置TranKey到返回报文中
		ack.tranKey = req.tranKey;

		// step 1: 假定业务失败
		ack.respCode = TuxedoRespCode.RC_DBERR;

		// step 2: 数据检查阶段
		preService(req, ack);

		// step 3: 流水号产生阶段

		// step 4: 业务逻辑阶段,如记载相关的数据库表

		Service(req, ack);

		// 返回,标记业务成功
		ack.respCode = TuxedoRespCode.RC_SUCCESS;

		return ack;
	}

	/**
	 * 服务入口
	 * 
	 * @param req
	 * @return TransResponse
	 */
	public TransResponse Service(TransRequest req)
			throws PCPSApplicationException {
		return null;
	}

	private void logException(byte[] ibuf, Exception ex) {
		QueueConnection cnn = null;
		QueueSender sender = null;
		QueueSession sess = null;
		Queue queue = null;

		try {
			InitialContext ctx = new InitialContext();
			QueueConnectionFactory factory = (QueueConnectionFactory) ctx
					.lookup("weblogic.jms.ConnectionFactory");
			cnn = factory.createQueueConnection();
			sess = cnn.createQueueSession(false,
					QueueSession.CLIENT_ACKNOWLEDGE);
			queue = (Queue) ctx.lookup("DayOffImplQueue");
			ObjectMessage msg = sess.createObjectMessage();
			Object[] obj = new Object[3];
			obj[0] = "LOGEXCEPTION";
			obj[1] = ibuf;
			obj[2] = ex;
			msg.setObject(obj);
			sender = sess.createSender(queue);
			sender.send(msg);
			sess.close();
			cnn.close();
		} catch (Exception e) {
		}
	}

	/**
	 * 按传入的字节数组执行交易,由tuxedo的代理组件来调用
	 * 
	 * @param ibuf
	 * @return
	 */
	public byte[] Service(byte[] ibuf) {
		byte[] obuf = null;
		TransRequest req = null;
		TransResponse ack = null;

		try {
			// step 1: 产生请求和应答对象
			req = makeRequestObject();

			// step 2: 解析数据到请求对象中
			req.parseXml(ibuf);

			// 设置不同的跟踪日志
			PCPSUtil.setMrchLogEntry(req.merchantNo, req.posObj.posNo,
					req.tranCode);

			// step 3: 执行具体的服务
			ack = Service(req);

			// step 4: 打包数据
			obuf = ack.constructXml();
		} catch (Exception pae) {
			try {
				getEjbContext().setRollbackOnly();
				PCPSUtil.Log("EJBContext setRollbackOnly!");
			} catch (Exception ex) {
				PCPSUtil.Log("EJBContext setRollbackOnly failed!", ex);
			}

			ack = new TransResponse();
			if (req != null) {
				ack.tranCode = req.tranCode;
				ack.tranKey = req.tranKey;
			}
			if (pae instanceof PCPSApplicationException) {
				PCPSApplicationException p = (PCPSApplicationException) pae;
				ack.respCode = p.getSubSysErrCode();
				ack.respErrMsg = p.getErrMsg();
			} else
				ack.respCode = TuxedoRespCode.RC_DBERR;
			PCPSUtil.Log("Exception:", pae);
			// 加入到异常对列
			logException(ibuf, pae);
			try {
				obuf = ack.constructXml();
			} catch (Exception e) {
			}
		}

		// 返回数据
		return obuf;
	}
}
